package handler;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.*;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.ByteBuffer;

public class DownLoadHandler2 extends ChannelInboundHandlerAdapter
{
    private       File dir;
    private final int  maxContentLength = 1024 * 1024;

    public DownLoadHandler2(File dir)
    {
        this.dir = dir;
    }

    @Override
    public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception
    {
        FullHttpRequest fullHttpRequest = (FullHttpRequest) msg;
        String          uri             = fullHttpRequest.uri();
        uri = URLDecoder.decode(uri, "utf8");
        File dest = dir;
        for (final String each : uri.split("/"))
        {
            File[] files = dest.listFiles(new FileFilter()
            {
                @Override
                public boolean accept(File pathname)
                {
                    return pathname.getName().equals(each);
                }
            });
            if (files.length == 1)
            {
                dest = files[0];
            }
        }
        HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
        response.headers().add(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.APPLICATION_OCTET_STREAM);
        final FileInputStream inputStream = new FileInputStream(dest);
        response.headers().add(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.CHUNKED);
        response.headers().add(HttpHeaderNames.CONTENT_DISPOSITION,"attachment;filename="+ URLEncoder.encode(dest.getName(),"utf8"));
        ctx.write(response);
        ByteBuf               buffer      = ctx.alloc().buffer();
        int                   need        = Math.min(maxContentLength, inputStream.available());
        buffer.writeBytes(inputStream, need);
        ctx.channel().writeAndFlush(buffer).addListener(new GenericFutureListener<Future<? super Void>>()
        {
            @Override
            public void operationComplete(Future<? super Void> future) throws Exception
            {
                int need = Math.min(maxContentLength, inputStream.available());
                if (need != 0)
                {
                    ByteBuf buffer = ctx.alloc().buffer();
                    buffer.writeBytes(inputStream, need);
                    Thread.sleep(1000);
                    ctx.channel().writeAndFlush(buffer).addListener(this);
                }
                else
                {
                    inputStream.close();
                    ctx.channel().writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
                }
            }
        });
    }
}
